package com.koron.css2;

import com.koron.css2.serviceManage.bean.*;
import com.koron.css2.serviceManage.service.ServerService;
import com.koron.css2.serviceManage.utils.CommonUtils;
import com.koron.css2.serviceManage.utils.JsonUtils;
import com.koron.css2.serviceManage.utils.PageDetailLog;
import com.koron.util.Constant;
import com.koron.util.DBSourceUtils;
import com.koron.util.InitParam;
import com.koron.util.Tools;
import nl.bitwalker.useragentutils.UserAgent;
import org.apache.commons.lang3.StringUtils;
import org.koron.ebs.mybatis.ADOConnection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.swan.bean.MessageBean;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;


/**
 *
 */
@Controller
public class ExportPdfAction {

    /**
     * 服务管理类
     */
    @Resource
    private ServerService serverService;

    /**
     * 日志
     */
    private static Logger logger = LoggerFactory.getLogger(ExportPdfAction.class);

    /**
     * 用于存储查询过的服务配置信息，这里不放redis而是放本地内存，访问更快
     */
    private HashMap<String, TService> tServiceMap = new HashMap<>();

    /**
     * 用于存储所有接口的实例，在接口被调用一次之后，实例对象存储在这里，方便后续调用
     */
    private HashMap<String, ExportPdfInterface> serverMap = new HashMap<>();

    /**
     * 002营收系统
     */
    private static final String CUR_SERVICE_002 = "002";

    /**
     * 003服务分析系统
     */
    private static final String CUR_SERVICE_003 = "003";

    /**
     * 请求头key: url
     */
    private final String URL = "url";


    /**
     * 所有业务系统操作数据的统一入口
     *
     * @param json    请求的对象数据
     * @param request 请求Servlet对象
     * @return ResponseBean 返回结果
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value = ("/exportPdf.api"), method = RequestMethod.GET)
    public HttpEntity<?> service(@RequestParam(required = true, name = "json") String json, HttpServletRequest request) throws Exception {
        RequestBean requestBean = JsonUtils.jsonToPojo(json, RequestBean.class);
        // 数据有效性校验
        if (requestBean == null || StringUtils.isBlank(requestBean.getBusicode()) || StringUtils.isBlank(requestBean.getSysType())) {
            return new ResponseEntity<String>("请求的json格式不正确,或者参数为空", HttpStatus.OK);
        }
        // 获取用户信息(包括用户信息，用户可选水司信息，用户当前水司信息)
        UserInfoBean userInfo = Tools.getLoginBean(requestBean.getToken());
        if (userInfo == null) {
            return new ResponseEntity<String>("当前登录信息失效，请重新登录后再操作。", HttpStatus.UNAUTHORIZED);
        }
        // 获取服务信息
        TService tService = getInterfaceInfo(requestBean.getBusicode(), requestBean.getToken());
        if (tService == null) {
            return new ResponseEntity<String>(requestBean.getBusicode() + "服务不存在", HttpStatus.UNAUTHORIZED);
        }
        // 检查用户是否有该服务的权限
        if (!checkRight(userInfo, tService, request.getHeader(URL), requestBean)) {
            return new ResponseEntity<String>("您无当前操作的权限(" + requestBean.getBusicode() + ")", HttpStatus.UNAUTHORIZED);
        }
        HttpEntity<?> httpEntity = null;
        ResponseBean responseBean = new ResponseBean();
        // 执行服务
        try {
            String dbEnv = "_default";
            if (CUR_SERVICE_002.equals(userInfo.getCurService())) {
                // 主数据库
                if (tService.getDbMaster() == 1) {
                    dbEnv = DBSourceUtils.getDbEnv(userInfo.getCurWaterCode(), true);
                } else if (tService.getDbMaster() == 2) {
                    // 从数据库
                    dbEnv = DBSourceUtils.getDbEnv(userInfo.getCurWaterCode(), false);
                    logger.info("当前的数据源为从库：{}", dbEnv);
                } else {
                    // 为空则为主库
                    dbEnv = DBSourceUtils.getDbEnv(userInfo.getCurWaterCode());
                }
            }
            if (CUR_SERVICE_003.equals(userInfo.getCurService())) {
                //TODO
            }
            if (dbEnv == null) {
                throw new RuntimeException("水司编号为：" + userInfo.getCurWaterCode() + "的数据源注册失败！");
            }
            // 从缓存中获取服务实例
            ExportPdfInterface serverInterface = serverMap.get(requestBean.getBusicode());
            if (serverInterface == null) {
                serverInterface = (ExportPdfInterface) Class.forName(tService.getClassName()).newInstance();
                serverMap.put(requestBean.getBusicode(), serverInterface);
            }
            //根据不同的数据连接，通过业务实体对象，执行具体的服务信息
            ExportPdfInterface finalServerInterface = serverInterface;
            httpEntity = ADOConnection.runTask(dbEnv, (factory) -> {
                HttpEntity<?> ret = finalServerInterface.exportPdf(factory, userInfo, requestBean);
                if (ret == null) {
                    factory.close(false);
                    throw new RuntimeException("没有httpEntity返回！");
                }
                if (ret instanceof ResponseEntity<?>) {
                    if (HttpStatus.OK.value() != ((ResponseEntity<?>) ret).getStatusCodeValue()) {
                        factory.close(false);
                        if (ret.getBody() instanceof MessageBean<?>) {
                            throw new RuntimeException(((MessageBean<?>) ret.getBody()).getDescription());
                        }
                    }
                }
                return ret;
            }, HttpEntity.class);
            responseBean.setCode(Constant.MESSAGE_INT_SUCCESS);
            responseBean.setDescription("pdf导出成功");
        } catch (Exception e) {
            logger.error("pdf导出失败", e);
            responseBean.setCode(Constant.MESSAGE_INT_FAIL);
            responseBean.setDescription("pdf导出失败");
            httpEntity = new ResponseEntity<String>("pdf导出失败：" + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
        }
        RecordLog(request, responseBean, requestBean, userInfo);
        return httpEntity;
    }

    /**
     * 从本地内存读取服务配置，如果没有就从数据库读取
     *
     * @param busicode
     * @param token
     * @return
     */
    private TService getInterfaceInfo(String busicode, String token) {
        TService tService = tServiceMap.get(busicode);
        if (tService == null) {
            tService = ADOConnection.runTask("_default", serverService, "selectByServiceCode", TService.class,
                    busicode);
            if (!InitParam.isDev) {
                tServiceMap.put(busicode, tService);
            }
        }
        return tService;
    }

    /**
     * 检查用户权限
     *
     * @param userInfo
     * @param tService
     * @param url
     * @return
     */
    private boolean checkRight(UserInfoBean userInfo, TService tService, String url, RequestBean requestBean) {
        return true;
    }

    /**
     * 记录调用日志
     *
     * @param request
     * @param responseBean
     * @param requestBean
     * @param userInfo
     */
    private void RecordLog(HttpServletRequest request, ResponseBean responseBean, RequestBean requestBean, UserInfoBean userInfo) {
        try {
            RecordBean recordBean = new RecordBean();
            String ua = request.getHeader("User-Agent");
            UserAgent userAgent = UserAgent.parseUserAgentString(ua);
            String browser = userAgent.getBrowser().getName();
            recordBean.setBrowserType(browser);
            recordBean.setWaterGroup(userInfo.getCurWaterCode());
            if (StringUtils.isBlank(userInfo.getCurWaterCode())) {
                recordBean.setWaterGroup("运维平台");
            }
            recordBean.setComments("调用" + requestBean.getBusicode());
            recordBean.setIpAddr(CommonUtils.getIpAddress(request));
            if (!StringUtils.isBlank(request.getHeader(URL))) {
                recordBean.setPageAddr(request.getHeader(URL));
            } else {
                recordBean.setPageAddr("abc(请求头header中未传递url信息)");
            }
            recordBean.setCaller(userInfo.getUserInfo().getAcount());
            recordBean.setCreateName(userInfo.getUserInfo().getName());
            recordBean.setCreateTime(CommonUtils.getCurrentTime());
            recordBean.setServiceCode(requestBean.getBusicode());
            recordBean.setRequest(JsonUtils.objectToJson(requestBean));
            recordBean.setResponse(JsonUtils.objectToJson(responseBean));
            PageDetailLog.put(recordBean);
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
    }
}
